home *** CD-ROM | disk | FTP | other *** search
/ The Arsenal Files 8 / The Arsenal Files Collection #8 (Arsenal Computer) (1996).ISO / g_quake / cluster.zip / ITEMS.QC < prev    next >
Text File  |  1996-08-08  |  29KB  |  1,349 lines

  1. void() W_SetCurrentAmmo;
  2. /* ALL LIGHTS SHOULD BE 0 1 0 IN COLOR ALL OTHER ITEMS SHOULD
  3. BE .8 .3 .4 IN COLOR */
  4.  
  5.  
  6. void() SUB_regen =
  7. {
  8.     self.model = self.mdl;    // restore original model
  9.     self.solid = SOLID_TRIGGER; // allow it to be touched again
  10.     sound (self, CHAN_VOICE, "items/itembk2.wav", 1, ATTN_NORM);  // play respawn sound
  11.     setorigin (self, self.origin);
  12. };
  13.  
  14.  
  15.  
  16. /*QUAKED noclass (0 0 0) (-8 -8 -8) (8 8 8)
  17. prints a warning message when spawned
  18. */
  19. void() noclass =
  20. {
  21.     dprint ("noclass spawned at");
  22.     dprint (vtos(self.origin));
  23.     dprint ("\n");
  24.     remove (self);
  25. };
  26.  
  27.  
  28.  
  29. /*
  30. ============
  31. PlaceItem
  32.  
  33. plants the object on the floor
  34. ============
  35. */
  36. void() PlaceItem =
  37. {
  38.     local float oldz;
  39.  
  40.     self.mdl = self.model;    // so it can be restored on respawn
  41.     self.flags = FL_ITEM;   // make extra wide
  42.     self.solid = SOLID_TRIGGER;
  43.     self.movetype = MOVETYPE_TOSS;  
  44.     self.velocity = '0 0 0';
  45.     self.origin_z = self.origin_z + 6;
  46.     oldz = self.origin_z;
  47.     if (!droptofloor())
  48.     {
  49.         dprint ("Bonus item fell out of level at ");
  50.         dprint (vtos(self.origin));
  51.         dprint ("\n");
  52.         remove(self);
  53.         return;
  54.     }
  55. };
  56.  
  57. /*
  58. ============
  59. StartItem
  60.  
  61. Sets the clipping size and plants the object on the floor
  62. ============
  63. */
  64. void() StartItem =
  65. {
  66.     self.nextthink = time + 0.2;  // items start after other solids
  67.     self.think = PlaceItem;
  68. };
  69.  
  70. /*
  71. =========================================================================
  72.  
  73. HEALTH BOX
  74.  
  75. =========================================================================
  76. */
  77. //
  78. // T_Heal: add health to an entity, limiting health to max_health
  79. // "ignore" will ignore max_health limit
  80. //
  81. float (entity e, float healamount, float ignore) T_Heal =
  82. {
  83.     if (e.health <= 0)
  84.         return 0;
  85.     if ((!ignore) && (e.health >= other.max_health))
  86.         return 0;
  87.     healamount = ceil(healamount);
  88.  
  89.     e.health = e.health + healamount;
  90.     if ((!ignore) && (e.health >= other.max_health))
  91.         e.health = other.max_health;
  92.         
  93.     if (e.health > 250)
  94.         e.health = 250;
  95.     return 1;
  96. };
  97.  
  98. /*QUAKED item_health (.3 .3 1) (0 0 0) (32 32 32) rotten megahealth
  99. Health box. Normally gives 25 points.
  100. Rotten box heals 5-10 points,
  101. megahealth will add 100 health, then 
  102. rot you down to your maximum health limit, 
  103. one point per second.
  104. */
  105.  
  106. float H_ROTTEN = 1;
  107. float H_MEGA = 2;
  108. .float  healamount, healtype;
  109. void() health_touch;
  110. void() item_megahealth_rot;
  111.  
  112. void() item_health =
  113.     self.touch = health_touch;
  114.  
  115.     if (self.spawnflags & H_ROTTEN)
  116.     {
  117.         precache_model("maps/b_bh10.bsp");
  118.  
  119.         precache_sound("items/r_item1.wav");
  120.         setmodel(self, "maps/b_bh10.bsp");
  121.         self.noise = "items/r_item1.wav";
  122.         self.healamount = 15;
  123.         self.healtype = 0;
  124.     }
  125.     else
  126.     if (self.spawnflags & H_MEGA)
  127.     {
  128.         precache_model("maps/b_bh100.bsp");
  129.         precache_sound("items/r_item2.wav");
  130.         setmodel(self, "maps/b_bh100.bsp");
  131.         self.noise = "items/r_item2.wav";
  132.         self.healamount = 100;
  133.         self.healtype = 2;
  134.     }
  135.     else
  136.     {
  137.         precache_model("maps/b_bh25.bsp");
  138.         precache_sound("items/health1.wav");
  139.         setmodel(self, "maps/b_bh25.bsp");
  140.         self.noise = "items/health1.wav";
  141.         self.healamount = 25;
  142.         self.healtype = 1;
  143.     }
  144.     setsize (self, '0 0 0', '32 32 56');
  145.     StartItem ();
  146. };
  147.  
  148.  
  149. void() health_touch =
  150. {
  151.     local float amount;
  152.     local string  s;
  153.     
  154.     if (other.classname != "player")
  155.         return;
  156.     
  157.     if (self.healtype == 2) // Megahealth?  Ignore max_health...
  158.     {
  159.         if (other.health >= 250)
  160.             return;
  161.         if (!T_Heal(other, self.healamount, 1))
  162.             return;
  163.     }
  164.     else
  165.     {
  166.         if (!T_Heal(other, self.healamount, 0))
  167.             return;
  168.     }
  169.     
  170.     sprint(other, "You receive ");
  171.     s = ftos(self.healamount);
  172.     sprint(other, s);
  173.     sprint(other, " health\n");
  174.     
  175. // health touch sound
  176.     sound(other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  177.  
  178.     stuffcmd (other, "bf\n");
  179.     
  180.     self.model = string_null;
  181.     self.solid = SOLID_NOT;
  182.  
  183.     // Megahealth = rot down the player's super health
  184.     if (self.healtype == 2)
  185.     {
  186.         other.items = other.items | IT_SUPERHEALTH;
  187.         self.nextthink = time + 5;
  188.         self.think = item_megahealth_rot;
  189.         self.owner = other;
  190.     }
  191.     else
  192.     {
  193.         if (deathmatch != 2)    // deathmatch 2 is the silly old rules
  194.         {
  195.             if (deathmatch)
  196.                 self.nextthink = time + 20;
  197.             self.think = SUB_regen;
  198.         }
  199.     }
  200.     
  201.     activator = other;
  202.     SUB_UseTargets();       // fire all targets / killtargets
  203. };  
  204.  
  205. void() item_megahealth_rot =
  206. {
  207.     other = self.owner;
  208.     
  209.     if (other.health > other.max_health)
  210.     {
  211.         other.health = other.health - 1;
  212.         self.nextthink = time + 1;
  213.         return;
  214.     }
  215.  
  216. // it is possible for a player to die and respawn between rots, so don't
  217. // just blindly subtract the flag off
  218.     other.items = other.items - (other.items & IT_SUPERHEALTH);
  219.     
  220.     if (deathmatch == 1)  // deathmatch 2 is silly old rules
  221.     {
  222.         self.nextthink = time + 20;
  223.         self.think = SUB_regen;
  224.     }
  225. };
  226.  
  227. /*
  228. ===============================================================================
  229.  
  230. ARMOR
  231.  
  232. ===============================================================================
  233. */
  234.  
  235. void() armor_touch;
  236.  
  237. void() armor_touch =
  238. {
  239.     local float type, value, bit;
  240.     
  241.     if (other.health <= 0)
  242.         return;
  243.     if (other.classname != "player")
  244.         return;
  245.  
  246.     if (self.classname == "item_armor1")
  247.     {
  248.         type = 0.3;
  249.         value = 100;
  250.         bit = IT_ARMOR1;
  251.     }
  252.     if (self.classname == "item_armor2")
  253.     {
  254.         type = 0.6;
  255.         value = 150;
  256.         bit = IT_ARMOR2;
  257.     }
  258.     if (self.classname == "item_armorInv")
  259.     {
  260.         type = 0.8;
  261.         value = 200;
  262.         bit = IT_ARMOR3;
  263.     }
  264.     if (other.armortype*other.armorvalue >= type*value)
  265.         return;
  266.         
  267.     other.armortype = type;
  268.     other.armorvalue = value;
  269.     other.items = other.items - (other.items & (IT_ARMOR1 | IT_ARMOR2 | IT_ARMOR3)) + bit;
  270.  
  271.     self.solid = SOLID_NOT;
  272.     self.model = string_null;
  273.     if (deathmatch == 1)
  274.         self.nextthink = time + 20;
  275.     self.think = SUB_regen;
  276.  
  277.     sprint(other, "You got armor\n");
  278. // armor touch sound
  279.     sound(other, CHAN_ITEM, "items/armor1.wav", 1, ATTN_NORM);
  280.     stuffcmd (other, "bf\n");
  281.     
  282.     activator = other;
  283.     SUB_UseTargets();       // fire all targets / killtargets
  284. };
  285.  
  286.  
  287. /*QUAKED item_armor1 (0 .5 .8) (-16 -16 0) (16 16 32)
  288. */
  289.  
  290. void() item_armor1 =
  291. {
  292.     self.touch = armor_touch;
  293.     precache_model ("progs/armor.mdl");
  294.     setmodel (self, "progs/armor.mdl");
  295.     self.skin = 0;
  296.     setsize (self, '-16 -16 0', '16 16 56');
  297.     StartItem ();
  298. };
  299.  
  300. /*QUAKED item_armor2 (0 .5 .8) (-16 -16 0) (16 16 32)
  301. */
  302.  
  303. void() item_armor2 =
  304. {
  305.     self.touch = armor_touch;
  306.     precache_model ("progs/armor.mdl");
  307.     setmodel (self, "progs/armor.mdl");
  308.     self.skin = 1;
  309.     setsize (self, '-16 -16 0', '16 16 56');
  310.     StartItem ();
  311. };
  312.  
  313. /*QUAKED item_armorInv (0 .5 .8) (-16 -16 0) (16 16 32)
  314. */
  315.  
  316. void() item_armorInv =
  317. {
  318.     self.touch = armor_touch;
  319.     precache_model ("progs/armor.mdl");
  320.     setmodel (self, "progs/armor.mdl");
  321.     self.skin = 2;
  322.     setsize (self, '-16 -16 0', '16 16 56');
  323.     StartItem ();
  324. };
  325.  
  326. /*
  327. ===============================================================================
  328.  
  329. WEAPONS
  330.  
  331. ===============================================================================
  332. */
  333.  
  334. void() bound_other_ammo =
  335. {
  336.     if (other.ammo_shells > 100)
  337.         other.ammo_shells = 100;
  338.     if (other.ammo_nails > 200)
  339.         other.ammo_nails = 200;
  340.     if (other.ammo_rockets > 100)
  341.         other.ammo_rockets = 100;   
  342.     if (other.ammo_cells > 100)
  343.         other.ammo_cells = 100;   
  344. };
  345.  
  346.  
  347. float(float w) RankForWeapon =
  348. {
  349.     if (w == IT_LIGHTNING)
  350.         return 1;
  351.     if (w == IT_ROCKET_LAUNCHER)
  352.         return 3;
  353.     if (w == IT_SUPER_NAILGUN)
  354.         return 4;
  355.     if (w == IT_GRENADE_LAUNCHER)
  356.         return 7;
  357.     if (w == IT_SUPER_SHOTGUN)
  358.         return 8;
  359.     if (w == IT_NAILGUN)
  360.         return 9;
  361.     return 10;
  362. };
  363.  
  364. float(float w) RankForExtraWeapon1 =
  365. {
  366.     if (w == WP_CLUSTER)
  367.         return 5;
  368. };
  369. /*
  370. =============
  371. Deathmatch_Weapon
  372.  
  373. Deathmatch weapon change rules for picking up a weapon
  374.  
  375. .float    ammo_shells, ammo_nails, ammo_rockets, ammo_cells;
  376. =============
  377. */
  378. void(float old, float new) Deathmatch_Weapon =
  379. {
  380.     local float or, nr;
  381.     local entity tmp;
  382. // change self.weapon if desired
  383.     or = RankForWeapon (self.weapon);
  384.     if (self.ef & EXTRA_1)
  385.         or=RankForExtraWeapon1(self.weapon);
  386.     nr = RankForWeapon (new);
  387.     if ( nr < or )
  388.         self.weapon = new;
  389. };
  390.  
  391. /*
  392. =============
  393. weapon_touch
  394. =============
  395. */
  396. float() W_BestWeapon;
  397.  
  398. void() weapon_touch =
  399. {
  400.     local float hadammo, best, new, old;
  401.     local entity  stemp;
  402.     local float leave;
  403.  
  404.     if (!(other.flags & FL_CLIENT))
  405.         return;
  406.  
  407. // if the player was using his best weapon, change up to the new one if better    
  408.     stemp = self;
  409.     self = other;
  410.     best = W_BestWeapon();
  411.     self = stemp;
  412.  
  413.     if (deathmatch == 2 || coop)
  414.         leave = 1;
  415.     else
  416.         leave = 0;
  417.     
  418.     if (self.classname == "weapon_nailgun")
  419.     {
  420.         if (leave && (other.items & IT_NAILGUN) )
  421.             return;
  422.         hadammo = other.ammo_nails;     
  423.         new = IT_NAILGUN;
  424.         other.ammo_nails = other.ammo_nails + 30;
  425.     }
  426.     else if (self.classname == "weapon_supernailgun")
  427.     {
  428.         if (leave && (other.items & IT_SUPER_NAILGUN) )
  429.             return;
  430.         hadammo = other.ammo_rockets;     
  431.         new = IT_SUPER_NAILGUN;
  432.         other.ammo_nails = other.ammo_nails + 30;
  433.     }
  434.     else if (self.classname == "weapon_supershotgun")
  435.     {
  436.         if (leave && (other.items & IT_SUPER_SHOTGUN) )
  437.             return;
  438.         hadammo = other.ammo_rockets;     
  439.         new = IT_SUPER_SHOTGUN;
  440.         other.ammo_shells = other.ammo_shells + 5;
  441.     }
  442.     else if (self.classname == "weapon_rocketlauncher")
  443.     {
  444.         if (leave && (other.items & IT_ROCKET_LAUNCHER) )
  445.             return;
  446.         hadammo = other.ammo_rockets;     
  447.         new = IT_ROCKET_LAUNCHER;
  448.         other.ammo_rockets = other.ammo_rockets + 5;
  449.     }
  450.     else if (self.classname == "weapon_grenadelauncher")
  451.     {
  452.         if (leave && (other.items & IT_GRENADE_LAUNCHER) )
  453.             return;
  454.         hadammo = other.ammo_rockets;     
  455.         new = IT_GRENADE_LAUNCHER;
  456.         other.weapons1=other.weapons1|WP_CLUSTER;
  457.         other.ammo_rockets = other.ammo_rockets + 5;
  458.     }
  459.     else if (self.classname == "weapon_lightning")
  460.     {
  461.         if (leave && (other.items & IT_LIGHTNING) )
  462.             return;
  463.         hadammo = other.ammo_rockets;     
  464.         new = IT_LIGHTNING;
  465.         other.ammo_cells = other.ammo_cells + 15;
  466.     }
  467.     else
  468.         objerror ("weapon_touch: unknown classname");
  469.  
  470.     sprint (other, "You got the ");
  471.     sprint (other, self.netname);
  472.     sprint (other, "\n");
  473. // weapon touch sound
  474.     sound (other, CHAN_ITEM, "weapons/pkup.wav", 1, ATTN_NORM);
  475.     stuffcmd (other, "bf\n");
  476.  
  477.     bound_other_ammo ();
  478.  
  479. // change to the weapon
  480.     old = other.items;
  481.     other.items = other.items | new;
  482.     
  483.     stemp = self;
  484.     self = other;
  485.  
  486.     if (!deathmatch)
  487.         self.weapon = new;
  488.     else
  489.         Deathmatch_Weapon (old, new);
  490.  
  491.     W_SetCurrentAmmo();
  492.  
  493.     self = stemp;
  494.  
  495.     if (leave)
  496.         return;
  497.  
  498. // remove it in single player, or setup for respawning in deathmatch
  499.     self.model = string_null;
  500.     self.solid = SOLID_NOT;
  501.     if (deathmatch == 1)
  502.         self.nextthink = time + 30;
  503.     self.think = SUB_regen;
  504.     
  505.     activator = other;
  506.     SUB_UseTargets();       // fire all targets / killtargets
  507. };
  508.  
  509.  
  510. /*QUAKED weapon_supershotgun (0 .5 .8) (-16 -16 0) (16 16 32)
  511. */
  512.  
  513. void() weapon_supershotgun =
  514. {
  515.     precache_model ("progs/g_shot.mdl");
  516.     setmodel (self, "progs/g_shot.mdl");
  517.     self.weapon = IT_SUPER_SHOTGUN;
  518.     self.netname = "Double-barrelled Shotgun";
  519.     self.touch = weapon_touch;
  520.     setsize (self, '-16 -16 0', '16 16 56');
  521.     StartItem ();
  522. };
  523.  
  524. /*QUAKED weapon_nailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  525. */
  526.  
  527. void() weapon_nailgun =
  528. {
  529.     precache_model ("progs/g_nail.mdl");
  530.     setmodel (self, "progs/g_nail.mdl");
  531.     self.weapon = IT_NAILGUN;
  532.     self.netname = "nailgun";
  533.     self.touch = weapon_touch;
  534.     setsize (self, '-16 -16 0', '16 16 56');
  535.     StartItem ();
  536. };
  537.  
  538. /*QUAKED weapon_supernailgun (0 .5 .8) (-16 -16 0) (16 16 32)
  539. */
  540.  
  541. void() weapon_supernailgun =
  542. {
  543.     precache_model ("progs/g_nail2.mdl");
  544.     setmodel (self, "progs/g_nail2.mdl");
  545.     self.weapon = IT_SUPER_NAILGUN;
  546.     self.netname = "Super Nailgun";
  547.     self.touch = weapon_touch;
  548.     setsize (self, '-16 -16 0', '16 16 56');
  549.     StartItem ();
  550. };
  551.  
  552. /*QUAKED weapon_grenadelauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  553. */
  554.  
  555. void() weapon_grenadelauncher =
  556. {
  557.     precache_model ("progs/g_rock.mdl");
  558.     setmodel (self, "progs/g_rock.mdl");
  559.     self.weapon = 3;
  560.     self.netname = "Grenade Launcher";
  561.     self.touch = weapon_touch;
  562.     setsize (self, '-16 -16 0', '16 16 56');
  563.     StartItem ();
  564. };
  565.  
  566. /*QUAKED weapon_rocketlauncher (0 .5 .8) (-16 -16 0) (16 16 32)
  567. */
  568.  
  569. void() weapon_rocketlauncher =
  570. {
  571.     precache_model ("progs/g_rock2.mdl");
  572.     setmodel (self, "progs/g_rock2.mdl");
  573.     self.weapon = 3;
  574.     self.netname = "Rocket Launcher";
  575.     self.touch = weapon_touch;
  576.     setsize (self, '-16 -16 0', '16 16 56');
  577.     StartItem ();
  578. };
  579.  
  580.  
  581. /*QUAKED weapon_lightning (0 .5 .8) (-16 -16 0) (16 16 32)
  582. */
  583.  
  584. void() weapon_lightning =
  585. {
  586.     precache_model ("progs/g_light.mdl");
  587.     setmodel (self, "progs/g_light.mdl");
  588.     self.weapon = 3;
  589.     self.netname = "Thunderbolt";
  590.     self.touch = weapon_touch;
  591.     setsize (self, '-16 -16 0', '16 16 56');
  592.     StartItem ();
  593. };
  594.  
  595.  
  596. /*
  597. ===============================================================================
  598.  
  599. AMMO
  600.  
  601. ===============================================================================
  602. */
  603.  
  604. void() ammo_touch =
  605. {
  606. local entity  stemp;
  607. local float   best;
  608.  
  609.     if (other.classname != "player")
  610.         return;
  611.     if (other.health <= 0)
  612.         return;
  613.  
  614. // if the player was using his best weapon, change up to the new one if better    
  615.     stemp = self;
  616.     self = other;
  617.     best = W_BestWeapon();
  618.     self = stemp;
  619.  
  620.  
  621. // shotgun
  622.     if (self.weapon == 1)
  623.     {
  624.         if (other.ammo_shells >= 100)
  625.             return;
  626.         other.ammo_shells = other.ammo_shells + self.aflag;
  627.     }
  628.  
  629. // spikes
  630.     if (self.weapon == 2)
  631.     {
  632.         if (other.ammo_nails >= 200)
  633.             return;
  634.         other.ammo_nails = other.ammo_nails + self.aflag;
  635.     }
  636.  
  637. //  rockets
  638.     if (self.weapon == 3)
  639.     {
  640.         if (other.ammo_rockets >= 100)
  641.             return;
  642.         other.ammo_rockets = other.ammo_rockets + self.aflag;
  643.     }
  644.  
  645. //  cells
  646.     if (self.weapon == 4)
  647.     {
  648.         if (other.ammo_cells >= 200)
  649.             return;
  650.         other.ammo_cells = other.ammo_cells + self.aflag;
  651.     }
  652.  
  653.     bound_other_ammo ();
  654.     
  655.     sprint (other, "You got the ");
  656.     sprint (other, self.netname);
  657.     sprint (other, "\n");
  658. // ammo touch sound
  659.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  660.     stuffcmd (other, "bf\n");
  661.  
  662. // change to a better weapon if appropriate
  663.  
  664.     if ( other.weapon == best )
  665.     {
  666.         stemp = self;
  667.         self = other;
  668.         self.weapon = W_BestWeapon();
  669.         W_SetCurrentAmmo ();
  670.         self = stemp;
  671.     }
  672.  
  673. // if changed current ammo, update it
  674.     stemp = self;
  675.     self = other;
  676.     W_SetCurrentAmmo();
  677.     self = stemp;
  678.  
  679. // remove it in single player, or setup for respawning in deathmatch
  680.     self.model = string_null;
  681.     self.solid = SOLID_NOT;
  682.     if (deathmatch == 1)
  683.         self.nextthink = time + 30;
  684.     
  685.     self.think = SUB_regen;
  686.  
  687.     activator = other;
  688.     SUB_UseTargets();       // fire all targets / killtargets
  689. };
  690.  
  691.  
  692.  
  693.  
  694. float WEAPON_BIG2 = 1;
  695.  
  696. /*QUAKED item_shells (0 .5 .8) (0 0 0) (32 32 32) big
  697. */
  698.  
  699. void() item_shells =
  700. {
  701.     self.touch = ammo_touch;
  702.  
  703.     if (self.spawnflags & WEAPON_BIG2)
  704.     {
  705.         precache_model ("maps/b_shell1.bsp");
  706.         setmodel (self, "maps/b_shell1.bsp");
  707.         self.aflag = 40;
  708.     }
  709.     else
  710.     {
  711.         precache_model ("maps/b_shell0.bsp");
  712.         setmodel (self, "maps/b_shell0.bsp");
  713.         self.aflag = 20;
  714.     }
  715.     self.weapon = 1;
  716.     self.netname = "shells";
  717.     setsize (self, '0 0 0', '32 32 56');
  718.     StartItem ();
  719. };
  720.  
  721. /*QUAKED item_spikes (0 .5 .8) (0 0 0) (32 32 32) big
  722. */
  723.  
  724. void() item_spikes =
  725. {
  726.     self.touch = ammo_touch;
  727.  
  728.     if (self.spawnflags & WEAPON_BIG2)
  729.     {
  730.         precache_model ("maps/b_nail1.bsp");
  731.         setmodel (self, "maps/b_nail1.bsp");
  732.         self.aflag = 50;
  733.     }
  734.     else
  735.     {
  736.         precache_model ("maps/b_nail0.bsp");
  737.         setmodel (self, "maps/b_nail0.bsp");
  738.         self.aflag = 25;
  739.     }
  740.     self.weapon = 2;
  741.     self.netname = "nails";
  742.     setsize (self, '0 0 0', '32 32 56');
  743.     StartItem ();
  744. };
  745.  
  746. /*QUAKED item_rockets (0 .5 .8) (0 0 0) (32 32 32) big
  747. */
  748.  
  749. void() item_rockets =
  750. {
  751.     self.touch = ammo_touch;
  752.  
  753.     if (self.spawnflags & WEAPON_BIG2)
  754.     {
  755.         precache_model ("maps/b_rock1.bsp");
  756.         setmodel (self, "maps/b_rock1.bsp");
  757.         self.aflag = 10;
  758.     }
  759.     else
  760.     {
  761.         precache_model ("maps/b_rock0.bsp");
  762.         setmodel (self, "maps/b_rock0.bsp");
  763.         self.aflag = 5;
  764.     }
  765.     self.weapon = 3;
  766.     self.netname = "rockets";
  767.     setsize (self, '0 0 0', '32 32 56');
  768.     StartItem ();
  769. };
  770.  
  771.  
  772. /*QUAKED item_cells (0 .5 .8) (0 0 0) (32 32 32) big
  773. */
  774.  
  775. void() item_cells =
  776. {
  777.     self.touch = ammo_touch;
  778.  
  779.     if (self.spawnflags & WEAPON_BIG2)
  780.     {
  781.         precache_model ("maps/b_batt1.bsp");
  782.         setmodel (self, "maps/b_batt1.bsp");
  783.         self.aflag = 12;
  784.     }
  785.     else
  786.     {
  787.         precache_model ("maps/b_batt0.bsp");
  788.         setmodel (self, "maps/b_batt0.bsp");
  789.         self.aflag = 6;
  790.     }
  791.     self.weapon = 4;
  792.     self.netname = "cells";
  793.     setsize (self, '0 0 0', '32 32 56');
  794.     StartItem ();
  795. };
  796.  
  797.  
  798. /*QUAKED item_weapon (0 .5 .8) (0 0 0) (32 32 32) shotgun rocket spikes big
  799. DO NOT USE THIS!!!! IT WILL BE REMOVED!
  800. */
  801.  
  802. float WEAPON_SHOTGUN = 1;
  803. float WEAPON_ROCKET = 2;
  804. float WEAPON_SPIKES = 4;
  805. float WEAPON_BIG = 8;
  806. void() item_weapon =
  807. {
  808.     self.touch = ammo_touch;
  809.  
  810.     if (self.spawnflags & WEAPON_SHOTGUN)
  811.     {
  812.         if (self.spawnflags & WEAPON_BIG)
  813.         {
  814.             precache_model ("maps/b_shell1.bsp");
  815.             setmodel (self, "maps/b_shell1.bsp");
  816.             self.aflag = 40;
  817.         }
  818.         else
  819.         {
  820.             precache_model ("maps/b_shell0.bsp");
  821.             setmodel (self, "maps/b_shell0.bsp");
  822.             self.aflag = 20;
  823.         }
  824.         self.weapon = 1;
  825.         self.netname = "shells";
  826.     }
  827.  
  828.     if (self.spawnflags & WEAPON_SPIKES)
  829.     {
  830.         if (self.spawnflags & WEAPON_BIG)
  831.         {
  832.             precache_model ("maps/b_nail1.bsp");
  833.             setmodel (self, "maps/b_nail1.bsp");
  834.             self.aflag = 40;
  835.         }
  836.         else
  837.         {
  838.             precache_model ("maps/b_nail0.bsp");
  839.             setmodel (self, "maps/b_nail0.bsp");
  840.             self.aflag = 20;
  841.         }
  842.         self.weapon = 2;
  843.         self.netname = "spikes";
  844.     }
  845.  
  846.     if (self.spawnflags & WEAPON_ROCKET)
  847.     {
  848.         if (self.spawnflags & WEAPON_BIG)
  849.         {
  850.             precache_model ("maps/b_rock1.bsp");
  851.             setmodel (self, "maps/b_rock1.bsp");
  852.             self.aflag = 10;
  853.         }
  854.         else
  855.         {
  856.             precache_model ("maps/b_rock0.bsp");
  857.             setmodel (self, "maps/b_rock0.bsp");
  858.             self.aflag = 5;
  859.         }
  860.         self.weapon = 3;
  861.         self.netname = "rockets";
  862.     }
  863.     
  864.     setsize (self, '0 0 0', '32 32 56');
  865.     StartItem ();
  866. };
  867.  
  868.  
  869. /*
  870. ===============================================================================
  871.  
  872. KEYS
  873.  
  874. ===============================================================================
  875. */
  876.  
  877. void() key_touch =
  878. {
  879. local entity  stemp;
  880. local float   best;
  881.  
  882.     if (other.classname != "player")
  883.         return;
  884.     if (other.health <= 0)
  885.         return;
  886.     if (other.items & self.items)
  887.         return;
  888.  
  889.     sprint (other, "You got the ");
  890.     sprint (other, self.netname);
  891.     sprint (other,"\n");
  892.  
  893.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  894.     stuffcmd (other, "bf\n");
  895.     other.items = other.items | self.items;
  896.  
  897.     if (!coop)
  898.     { 
  899.         self.solid = SOLID_NOT;
  900.         self.model = string_null;
  901.     }
  902.  
  903.     activator = other;
  904.     SUB_UseTargets();       // fire all targets / killtargets
  905. };
  906.  
  907.  
  908. void() key_setsounds =
  909. {
  910.     if (world.worldtype == 0)
  911.     {
  912.         precache_sound ("misc/medkey.wav");
  913.         self.noise = "misc/medkey.wav";
  914.     }
  915.     if (world.worldtype == 1)
  916.     {
  917.         precache_sound ("misc/runekey.wav");
  918.         self.noise = "misc/runekey.wav";
  919.     }
  920.     if (world.worldtype == 2)
  921.     {
  922.         precache_sound2 ("misc/basekey.wav");
  923.         self.noise = "misc/basekey.wav";
  924.     }
  925. };
  926.  
  927. /*QUAKED item_key1 (0 .5 .8) (-16 -16 -24) (16 16 32)
  928. SILVER key
  929. In order for keys to work
  930. you MUST set your maps
  931. worldtype to one of the
  932. following:
  933. 0: medieval
  934. 1: metal
  935. 2: base
  936. */
  937.  
  938. void() item_key1 =
  939. {
  940.     if (world.worldtype == 0)
  941.     {
  942.         precache_model ("progs/w_s_key.mdl");
  943.         setmodel (self, "progs/w_s_key.mdl");
  944.         self.netname = "silver key";
  945.     }
  946.     else if (world.worldtype == 1)
  947.     {
  948.         precache_model ("progs/m_s_key.mdl");
  949.         setmodel (self, "progs/m_s_key.mdl");
  950.         self.netname = "silver runekey";
  951.     }
  952.     else if (world.worldtype == 2)
  953.     {
  954.         precache_model2 ("progs/b_s_key.mdl");
  955.         setmodel (self, "progs/b_s_key.mdl");
  956.         self.netname = "silver keycard";
  957.     }
  958.     key_setsounds();
  959.     self.touch = key_touch;
  960.     self.items = IT_KEY1;
  961.     setsize (self, '-16 -16 -24', '16 16 32');
  962.     StartItem ();
  963. };
  964.  
  965. /*QUAKED item_key2 (0 .5 .8) (-16 -16 -24) (16 16 32)
  966. GOLD key
  967. In order for keys to work
  968. you MUST set your maps
  969. worldtype to one of the
  970. following:
  971. 0: medieval
  972. 1: metal
  973. 2: base
  974. */
  975.  
  976. void() item_key2 =
  977. {
  978.     if (world.worldtype == 0)
  979.     {
  980.         precache_model ("progs/w_g_key.mdl");
  981.         setmodel (self, "progs/w_g_key.mdl");
  982.         self.netname = "gold key";
  983.     }
  984.     if (world.worldtype == 1)
  985.     {
  986.         precache_model ("progs/m_g_key.mdl");
  987.         setmodel (self, "progs/m_g_key.mdl");
  988.         self.netname = "gold runekey";
  989.     }
  990.     if (world.worldtype == 2)
  991.     {
  992.         precache_model2 ("progs/b_g_key.mdl");
  993.         setmodel (self, "progs/b_g_key.mdl");
  994.         self.netname = "gold keycard";
  995.     }
  996.     key_setsounds();
  997.     self.touch = key_touch;
  998.     self.items = IT_KEY2;
  999.     setsize (self, '-16 -16 -24', '16 16 32');
  1000.     StartItem ();
  1001. };
  1002.  
  1003.  
  1004.  
  1005. /*
  1006. ===============================================================================
  1007.  
  1008. END OF LEVEL RUNES
  1009.  
  1010. ===============================================================================
  1011. */
  1012.  
  1013. void() sigil_touch =
  1014. {
  1015. local entity  stemp;
  1016. local float   best;
  1017.  
  1018.     if (other.classname != "player")
  1019.         return;
  1020.     if (other.health <= 0)
  1021.         return;
  1022.  
  1023.     centerprint (other, "You got the rune!");
  1024.  
  1025.     sound (other, CHAN_ITEM, self.noise, 1, ATTN_NORM);
  1026.     stuffcmd (other, "bf\n");
  1027.     self.solid = SOLID_NOT;
  1028.     self.model = string_null;
  1029.     serverflags = serverflags | (self.spawnflags & 15);
  1030.     self.classname = "";    // so rune doors won't find it
  1031.     
  1032.     activator = other;
  1033.     SUB_UseTargets();       // fire all targets / killtargets
  1034. };
  1035.  
  1036.  
  1037. /*QUAKED item_sigil (0 .5 .8) (-16 -16 -24) (16 16 32) E1 E2 E3 E4
  1038. End of level sigil, pick up to end episode and return to jrstart.
  1039. */
  1040.  
  1041. void() item_sigil =
  1042. {
  1043.     if (!self.spawnflags)
  1044.         objerror ("no spawnflags");
  1045.  
  1046.     precache_sound ("misc/runekey.wav");
  1047.     self.noise = "misc/runekey.wav";
  1048.  
  1049.     if (self.spawnflags & 1)
  1050.     {
  1051.         precache_model ("progs/end1.mdl");
  1052.         setmodel (self, "progs/end1.mdl");
  1053.     }
  1054.     if (self.spawnflags & 2)
  1055.     {
  1056.         precache_model2 ("progs/end2.mdl");
  1057.         setmodel (self, "progs/end2.mdl");
  1058.     }
  1059.     if (self.spawnflags & 4)
  1060.     {
  1061.         precache_model2 ("progs/end3.mdl");
  1062.         setmodel (self, "progs/end3.mdl");
  1063.     }
  1064.     if (self.spawnflags & 8)
  1065.     {
  1066.         precache_model2 ("progs/end4.mdl");
  1067.         setmodel (self, "progs/end4.mdl");
  1068.     }
  1069.     
  1070.     self.touch = sigil_touch;
  1071.     setsize (self, '-16 -16 -24', '16 16 32');
  1072.     StartItem ();
  1073. };
  1074.  
  1075. /*
  1076. ===============================================================================
  1077.  
  1078. POWERUPS
  1079.  
  1080. ===============================================================================
  1081. */
  1082.  
  1083. void() powerup_touch;
  1084.  
  1085.  
  1086. void() powerup_touch =
  1087. {
  1088. local entity  stemp;
  1089. local float   best;
  1090.  
  1091.     if (other.classname != "player")
  1092.         return;
  1093.     if (other.health <= 0)
  1094.         return;
  1095.  
  1096.     sprint (other, "You got the ");
  1097.     sprint (other, self.netname);
  1098.     sprint (other,"\n");
  1099.  
  1100.     if (deathmatch)
  1101.     {
  1102.         self.mdl = self.model;
  1103.         
  1104.         if ((self.classname == "item_artifact_invulnerability") ||
  1105.             (self.classname == "item_artifact_invisibility"))
  1106.             self.nextthink = time + 60*5;
  1107.         else
  1108.             self.nextthink = time + 60;
  1109.         
  1110.         self.think = SUB_regen;
  1111.     } 
  1112.  
  1113.     sound (other, CHAN_VOICE, self.noise, 1, ATTN_NORM);
  1114.     stuffcmd (other, "bf\n");
  1115.     self.solid = SOLID_NOT;
  1116.     other.items = other.items | self.items;
  1117.     self.model = string_null;
  1118.  
  1119. // do the apropriate action
  1120.     if (self.classname == "item_artifact_envirosuit")
  1121.     {
  1122.         other.rad_time = 1;
  1123.         other.radsuit_finished = time + 30;
  1124.     }
  1125.     
  1126.     if (self.classname == "item_artifact_invulnerability")
  1127.     {
  1128.         other.invincible_time = 1;
  1129.         other.invincible_finished = time + 30;
  1130.     }
  1131.     
  1132.     if (self.classname == "item_artifact_invisibility")
  1133.     {
  1134.         other.invisible_time = 1;
  1135.         other.invisible_finished = time + 30;
  1136.     }
  1137.  
  1138.     if (self.classname == "item_artifact_super_damage")
  1139.     {
  1140.         other.super_time = 1;
  1141.         other.super_damage_finished = time + 30;
  1142.     } 
  1143.  
  1144.     activator = other;
  1145.     SUB_UseTargets();       // fire all targets / killtargets
  1146. };
  1147.  
  1148.  
  1149.  
  1150. /*QUAKED item_artifact_invulnerability (0 .5 .8) (-16 -16 -24) (16 16 32)
  1151. Player is invulnerable for 30 seconds
  1152. */
  1153. void() item_artifact_invulnerability =
  1154. {
  1155.     self.touch = powerup_touch;
  1156.  
  1157.     precache_model ("progs/invulner.mdl");
  1158.     precache_sound ("items/protect.wav");
  1159.     precache_sound ("items/protect2.wav");
  1160.     precache_sound ("items/protect3.wav");
  1161.     self.noise = "items/protect.wav";
  1162.     setmodel (self, "progs/invulner.mdl");
  1163.     self.netname = "Pentagram of Protection";
  1164.     self.items = IT_INVULNERABILITY;
  1165.     setsize (self, '-16 -16 -24', '16 16 32');
  1166.     StartItem ();
  1167. };
  1168.  
  1169. /*QUAKED item_artifact_envirosuit (0 .5 .8) (-16 -16 -24) (16 16 32)
  1170. Player takes no damage from water or slime for 30 seconds
  1171. */
  1172. void() item_artifact_envirosuit =
  1173. {
  1174.     self.touch = powerup_touch;
  1175.  
  1176.     precache_model ("progs/suit.mdl");
  1177.     precache_sound ("items/suit.wav");
  1178.     precache_sound ("items/suit2.wav");
  1179.     self.noise = "items/suit.wav";
  1180.     setmodel (self, "progs/suit.mdl");
  1181.     self.netname = "Biosuit";
  1182.     self.items = IT_SUIT;
  1183.     setsize (self, '-16 -16 -24', '16 16 32');
  1184.     StartItem ();
  1185. };
  1186.  
  1187.  
  1188. /*QUAKED item_artifact_invisibility (0 .5 .8) (-16 -16 -24) (16 16 32)
  1189. Player is invisible for 30 seconds
  1190. */
  1191. void() item_artifact_invisibility =
  1192. {
  1193.     self.touch = powerup_touch;
  1194.  
  1195.     precache_model ("progs/invisibl.mdl");
  1196.     precache_sound ("items/inv1.wav");
  1197.     precache_sound ("items/inv2.wav");
  1198.     precache_sound ("items/inv3.wav");
  1199.     self.noise = "items/inv1.wav";
  1200.     setmodel (self, "progs/invisibl.mdl");
  1201.     self.netname = "Ring of Shadows";
  1202.     self.items = IT_INVISIBILITY;
  1203.     setsize (self, '-16 -16 -24', '16 16 32');
  1204.     StartItem ();
  1205. };
  1206.  
  1207.  
  1208. /*QUAKED item_artifact_super_damage (0 .5 .8) (-16 -16 -24) (16 16 32)
  1209. The next attack from the player will do 4x damage
  1210. */
  1211. void() item_artifact_super_damage =
  1212. {
  1213.     self.touch = powerup_touch;
  1214.  
  1215.     precache_model ("progs/quaddama.mdl");
  1216.     precache_sound ("items/damage.wav");
  1217.     precache_sound ("items/damage2.wav");
  1218.     precache_sound ("items/damage3.wav");
  1219.     self.noise = "items/damage.wav";
  1220.     setmodel (self, "progs/quaddama.mdl");
  1221.     self.netname = "Quad Damage";
  1222.     self.items = IT_QUAD;
  1223.     setsize (self, '-16 -16 -24', '16 16 32');
  1224.     StartItem ();
  1225. };
  1226.  
  1227.  
  1228.  
  1229. /*
  1230. ===============================================================================
  1231.  
  1232. PLAYER BACKPACKS
  1233.  
  1234. ===============================================================================
  1235. */
  1236.  
  1237. void() BackpackTouch =
  1238. {
  1239.     local string  s;
  1240.     local float best;
  1241.     local   entity  stemp;
  1242.     
  1243.     if (other.classname != "player")
  1244.         return;
  1245.     if (other.health <= 0)
  1246.         return;
  1247.         
  1248. // if the player was using his best weapon, change up to the new one if better    
  1249.     stemp = self;
  1250.     self = other;
  1251.     best = W_BestWeapon();
  1252.     self = stemp;
  1253.  
  1254. // change weapons
  1255.     other.ammo_shells = other.ammo_shells + self.ammo_shells;
  1256.     other.ammo_nails = other.ammo_nails + self.ammo_nails;
  1257.     other.ammo_rockets = other.ammo_rockets + self.ammo_rockets;
  1258.     other.ammo_cells = other.ammo_cells + self.ammo_cells;
  1259.  
  1260.     other.items = other.items | self.items;
  1261.     
  1262.     bound_other_ammo ();
  1263.  
  1264.     sprint (other, "You get ");
  1265.  
  1266.     if (self.ammo_shells)
  1267.     {
  1268.         s = ftos(self.ammo_shells);
  1269.         sprint (other, s);
  1270.         sprint (other, " shells  ");
  1271.     }
  1272.     if (self.ammo_nails)
  1273.     {
  1274.         s = ftos(self.ammo_nails);
  1275.         sprint (other, s);
  1276.         sprint (other, " nails ");
  1277.     }
  1278.     if (self.ammo_rockets)
  1279.     {
  1280.         s = ftos(self.ammo_rockets);
  1281.         sprint (other, s);
  1282.         sprint (other, " rockets  ");
  1283.     }
  1284.     if (self.ammo_cells)
  1285.     {
  1286.         s = ftos(self.ammo_cells);
  1287.         sprint (other, s);
  1288.         sprint (other, " cells  ");
  1289.     }
  1290.     
  1291.     sprint (other, "\n");
  1292. // backpack touch sound
  1293.     sound (other, CHAN_ITEM, "weapons/lock4.wav", 1, ATTN_NORM);
  1294.     stuffcmd (other, "bf\n");
  1295.  
  1296. // change to a better weapon if appropriate
  1297.     if ( other.weapon == best )
  1298.     {
  1299.         stemp = self;
  1300.         self = other;
  1301.         self.weapon = W_BestWeapon();
  1302.         self = stemp;
  1303.     }
  1304.  
  1305.     
  1306.     remove(self);
  1307.     
  1308.     self = other;
  1309.     W_SetCurrentAmmo ();
  1310. };
  1311.  
  1312. /*
  1313. ===============
  1314. DropBackpack
  1315. ===============
  1316. */
  1317. void() DropBackpack =
  1318. {
  1319.     local entity  item;
  1320.  
  1321.     if (!(self.ammo_shells + self.ammo_nails + self.ammo_rockets + self.ammo_cells))
  1322.         return; // nothing in it
  1323.  
  1324.     item = spawn();
  1325.     item.origin = self.origin - '0 0 24';
  1326.     
  1327.     item.items = self.weapon;
  1328.  
  1329.     item.ammo_shells = self.ammo_shells;
  1330.     item.ammo_nails = self.ammo_nails;
  1331.     item.ammo_rockets = self.ammo_rockets;
  1332.     item.ammo_cells = self.ammo_cells;
  1333.  
  1334.     item.velocity_z = 300;
  1335.     item.velocity_x = -100 + (random() * 200);
  1336.     item.velocity_y = -100 + (random() * 200);
  1337.     
  1338.     item.flags = FL_ITEM;
  1339.     item.solid = SOLID_TRIGGER;
  1340.     item.movetype = MOVETYPE_TOSS;
  1341.     setmodel (item, "progs/backpack.mdl");
  1342.     setsize (item, '-16 -16 0', '16 16 56');
  1343.     item.touch = BackpackTouch;
  1344.     
  1345.     item.nextthink = time + 120;  // remove after 2 minutes
  1346.     item.think = SUB_Remove;
  1347. };
  1348.